﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Wise.Util.Queryable
{
    /// <summary>
    /// 查询信息/查询参数集合
    /// 字段使用-前缀，表示模糊匹配 如（-Asset_Name）
    /// 字段以>开头，表示字段值大于参数值
    /// 以此类推，支持大于、大于等于、小于、小于等于
    /// 当存在大小比较就不再作为模糊查找
    /// </summary>
    public class _Parameter : _Entity
    {
        protected readonly MyQuery Parent = null;

        private string _ToString = null;
        /// <summary>
        /// JSON字符串表示形式
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (_ToString == null)
            {
                _ToString = string.Concat("{\"", Field, "\":\"", Value.ToString(), "\"}");
            }
            return _ToString;
        }

        /// <summary>
        /// 查询参数
        /// 字段各单词间使用下划线分隔，表示模糊匹配
        /// 字段各单词间无分隔符，表示精确匹配
        /// </summary>
        public _Parameter(MyQuery parent)
            : base()
        {
            Parent = parent;
        }
        /// <summary>
        /// 查询参数
        /// 字段各单词间使用下划线分隔，表示模糊匹配
        /// 字段各单词间无分隔符，表示精确匹配
        /// </summary>
        public _Parameter(MyQuery parent, string field)
            : this(parent)
        {
            this.Field = field;
        }
        /// <summary>
        /// 查询参数
        /// 字段各单词间使用下划线分隔，表示模糊匹配
        /// 字段各单词间无分隔符，表示精确匹配
        /// </summary>
        public _Parameter(MyQuery parent, string field, Object data)
            : this(parent)
        {
            this.Field = field;
            if (data is string)
            {
                this.Value = data;
            }
            else
            {
                this.Value = data;
            }
        }

        /// <summary>
        /// 查询参数,仅用于Json序列化
        /// </summary>
        /// <param name="value"></param>
        public _Parameter(string value)
        {
            this.Value = value;
        }

        private string _Field = string.Empty;
        /// <summary>
        /// 字段名称
        /// </summary>

        public string Field
        {
            get
            {
                return _Field;
            }
            set
            {
                if (string.Equals(Field, value))
                {
                    return;
                }
                if (value == null)
                    _Field = string.Empty;
                else
                {
                    //SecurityHelper.CheckSql(value);
                    _Field = value.Trim();
                }
                SendPropertyChanged("Field");
            }
        }

        private object _Value = DBNull.Value;

        /// <summary>
        /// 匹配值
        /// </summary>
        public object Value
        {
            get { return _Value; }
            set
            {
                if (value == _Value) return;
                if (value == null)
                    _Value = DBNull.Value;
                else
                {
                    string strValue = value == null ? string.Empty : value.ToString();
                    switch (this.Field)
                    {
                        case "_DataViewName":
                            break;
                        default:
                            //SecurityHelper.CheckSql(strValue);
                            break;
                    }
                    if (value is string)
                    {
                        _Value = value.ToString().Trim();
                    }
                    else
                    {
                        _Value = value;
                    }
                }
                SendPropertyChanged("Value");
            }
        }

        private readonly _WeekDictionary<Type, object> _Cache = new _WeekDictionary<Type, object>();

        /// <summary>
        /// 属性变化时
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        protected override bool OnPropertyChanged(string propertyName)
        {
            switch (propertyName)
            {
                case "Value":
                    _Cache.Clear();
                    if (Parent != null)
                    {
                        Parent.SendPropertyChanged(this.Field);
                    }
                    break;

            }

            _ToString = null;
            return true;
        }

        /// <summary>
        /// 获取值类型值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetValue<T>() where T : struct
        {
            if (IsNull) return default(T);
            return Value.ChangeTo<T>();
            //return NullHelper.Parse<T>(Value);
        }

        /// <summary>
        /// 获取值类型值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Nullable<T> GetNullableValue<T>()
            where T : struct
        {
            if (IsNull) return null;
            return NullHelper.ParseToNullable<T>(Value);
        }

        /// <summary>
        /// 获取引用类型值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetRefValue<T>() where T : class
        {
            if (IsNull) return default(T);
            Type type = typeof(T);
            return (T)_Cache.GetOrCreate(type, () =>
            {
                //try
                //{
                return Value.ChangeTo(type);
                //return ObjectHelper.ChangeType(Value, type);
                //}
                //catch (Exception exp)
                //{
                //    Exception e = new Exception(
                //        string.Format("字段[{0}]，值[{1}],无法转换成类型[{2}]", Field, Value, type.FullName), exp);
                //    LoggerHelper.Log(e, Loggers.LoggerType.INVALID_FOMART);
                //}
                //return null;
            });
        }

        /// <summary>
        /// 获取值或默认值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public T GetValueOrDefault<T>(T defaultValue) 
            where T : struct
        {
            if (IsNull)
                return defaultValue;
            return GetValue<T>(); 
        }

        /// <summary>
        /// 获取值或默认值
        /// </summary>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string GetStringOrDefault(String defaultValue)
        {
            if (IsNull)
                return defaultValue;
            return Value.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public Guid GuidValue
        {
            get
            {
                return GetValue<Guid>();
            }
        }

        /// <summary>
        /// 获取布尔值
        /// </summary>
        [XmlIgnore]
        public bool BoolenValue
        {
            get { return GetValue<Boolean>(); }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public int IntValue
        {
            get
            {
                return GetValue<int>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public int? NullIntValue
        {
            get
            {
                return IsNull ? null : (int?)IntValue;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public long Int64Value
        {
            get
            {
                return GetValue<long>();
            }
        }


        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public double DoubleValue
        {
            get
            {
                return GetValue<double>();
            }
        }


        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public Decimal DecimalValue
        {
            get
            {
                return GetValue<Decimal>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public float SingleValue
        {
            get
            {
                return GetValue<Single>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public Byte ByteValue
        {
            get
            {
                return GetValue<Byte>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public short Int16Value
        {
            get
            {
                return GetValue<short>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public string StringValue
        {
            get
            {
                return IsNull ? string.Empty : Value.ToString();
            }
        }

        /// <summary>
        /// 判断当前值是否为空
        /// </summary>
        [XmlIgnore]
        public bool IsNull
        {
            get
            {
                return NullHelper.IsJsNull(Value)
                    || NullHelper.IsDbNull(Value)
                    || NullHelper.IsDateNull(Value)
                    || NullHelper.IsStringNull(Value);
            }
        }

        /// <summary>
        /// 判断当前值是否不为空
        /// </summary>
        [XmlIgnore]
        public bool IsNotNull
        {
            get
            {
                return !IsNull;
            }
        }

        /// <summary>
        /// 判断当前值是否不是序列
        /// </summary>
        [XmlIgnore]
        public bool IsNotArray
        {
            get
            {
                return Value != null && !Field.StartsWith("@") && !Field.StartsWith("!");
            }
        }
    }
}
